package com.itheima.d2_bigdecimal;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 重要：
 * 在idea有时候是在忘记了代码该怎么写，就按住：ctrl+alt+空格，会给出相应的代码提示，
 * 例如：RoundingMode.HALF_UP就是按照提示写的
 *
 * BigDecimal也就是把接受的数据变成字符串，然后存放在数组中进行运算，最后封装为BigDecimal对象，
 * 可以debug看到，阿里巴巴开发手册也有BigDecimal的使用规范说明
 *
 */

/**
 * BigDecimal的作用是什么 ？
 * 解决浮点型运算时，出现结果失真的问题。
 * 应该如何把浮点型转换成BigDecimal的对象？
 * BigDecimal b1 = BigDecimal.valueOf(0.1)
 */
public class Test2 {
    public static void main(String[] args) {
        // 目标：掌握BigDecimal进行精确运算的方案。
        double a = 0.1;
        double b = 0.2;
        double m1 = 0.7;

        // 1、把浮点型数据封装成BigDecimal对象，再来参与运算。
        // a、构造器：public BigDecimal(double val) 得到的BigDecimal对象是无法精确计算浮点型数据的。 注意：不推荐使用这个，

        // b、构造器：public BigDecimal(String val)  得到的BigDecimal对象是可以精确计算浮点型数据的。 可以使用。
        // BigDecimal也就是把接受的数据变成字符串，然后存放在数组中进行运算，最后封装为BigDecimal对象，可以debug看到，阿里巴巴开发手册也有
        BigDecimal s1 = new BigDecimal(Double.toString(a));
        BigDecimal s2 = new BigDecimal(Double.toString(b));     //简化为下面的valueOf方法

        // c、public static BigDecimal valueOf(double val): 通过这个静态方法得到的BigDecimal对象是可以精确运算的。是最好的方案。
        //看valueOf的源码，就是底层把相关的代码封装了：return new BigDecimal(Double.toString(val));
        BigDecimal a1 = BigDecimal.valueOf(a);
        BigDecimal b1 = BigDecimal.valueOf(b);
        BigDecimal m2 = BigDecimal.valueOf(m1);

        System.out.println("========加法========");
        // 2、public BigDecimal add(BigDecimal augend): 加法
        BigDecimal c1 = a1.add(b1);
        System.out.println(c1);         //没有输出c1对象的地址，说明也重写了tostring方法
        System.out.println(a1.add(m2));

        System.out.println("========减法========");
        // 3、public BigDecimal subtract(BigDecimal augend): 减法
        BigDecimal c2 = a1.subtract(b1);
        System.out.println(c2);
        System.out.println(a1.subtract(m2));
        System.out.println(m2.subtract(a1));

        System.out.println("========乘法========");
        // 4、public BigDecimal multiply(BigDecimal augend): 乘法
        BigDecimal c3 = a1.multiply(b1);
        System.out.println(c3);
        System.out.println(a1.multiply(m2));

        System.out.println("========除法========");
        // 5、public BigDecimal divide(BigDecimal b): 除法
        BigDecimal c4 = a1.divide(b1);
        System.out.println("c4=:"+c4);
        System.out.println(m2.divide(b1));

/*        会报错，因为1/3不是精确结果，所以要给定精确到小数点多少位，也就是下面的示例方法
        BigDecimal d1 = BigDecimal.valueOf(0.1);
        BigDecimal d2 = BigDecimal.valueOf(0.3);
        BigDecimal d3 = d1.divide(d2);
        System.out.println(d3);*/

        System.out.println("========除法，可以设置精确几位========");
        // 6、public BigDecimal divide(另一个BigDecimal对象，精确几位，舍入模式) : 除法，可以设置精确几位。
        BigDecimal d1 = BigDecimal.valueOf(0.1);
        BigDecimal d2 = BigDecimal.valueOf(0.3);
        //在idea有时候是在忘记了代码该怎么写，就按住：ctrl+alt+空格，会给出相应的代码提示，例如：RoundingMode.HALF_UP就是按照提示写的
        BigDecimal d3 = d1.divide(d2,  2,RoundingMode.HALF_UP); // 0.33
        System.out.println(d3);
        System.out.println(m2.divide(d2,3,RoundingMode.HALF_UP));  //0.7/0.3: 2.333


        //以上例如BigDecimal是为了解决精度问题，最终业务基本都是需要八大基本数据类型，所以最终需要转换
        System.out.println("========BigDecimal对象又转换成double类型的数据========");
        // 7、public double doubleValue() : 把BigDecimal对象又转换成double类型的数据。
        //print(d3); //报错，BigDecimal和double不一样
        //print(c1);
        double db1 = d3.doubleValue();
        double db2 = c1.doubleValue();
        print(db1);
        print(db2);
        System.out.println(db2);
    }

    public static void print(double a){
        System.out.println(a);
    }
}
